package com.zan.backend.exception;

import com.zan.backend.common.BaseResponse;
import com.zan.backend.enums.CommonBaseErrorEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @Author Zan
 * @Create 2024/3/15 16:29
 * @Description : 自定义controller异常处理
 */
@RestControllerAdvice // 对所有controller发生异常的处理
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public BaseResponse<?> methodArgumentNotValidException(MethodArgumentNotValidException e) {
        StringBuilder errorMsg = new StringBuilder();
        e.getBindingResult().getFieldErrors().forEach(x -> errorMsg.append(x.getField()).append(x.getDefaultMessage()).append(","));
        String message = errorMsg.toString();
        return BaseResponse.fail(CommonBaseErrorEnum.PARAM_INVALID.getCode(), message.substring(0, message.length() - 1));
    }

    /**
     * 业务异常 - 由于这是被捕获的异常，所以传进来的e是已经经过构造器的e，相当于已经赋值了，并且是protected类型的，因此如果要使用e里面的属性，e的属性不能是private的
     */
    @ExceptionHandler(value = BusinessException.class)
    public BaseResponse<?> businessException(BusinessException e) {
        log.info("business exception! The reason is: {}", e.getErrorMsg(), e);
        return BaseResponse.fail(e.errorCode, e.errorMsg);
    }

    /**
     * 最终的兜底异常 - 最后一道防线
     * 如果没有，则会在前端爆出500异常 Internal Server Error，导致前端无法识别到，会出现报错
     */
    @ExceptionHandler(value = Throwable.class)
    public BaseResponse<?> throwable(Throwable e) {
        log.error("system exception! The reason is: {}", e.getMessage(), e);
        return BaseResponse.fail(CommonBaseErrorEnum.SYSTEM_ERROR);
    }

}
